#include <string>
#include <exception>

using namespace std;

class ex06da {
// [[ex06da]]
class myclass 
{
public:
	std::string str_;
};
// END
};

class ex06db {
// [[ex06db]]
// DEBUG descr An object with complex components referred by pointers.
class myclass 
{
public:
	myclass() :
		str_(new std::string)
	{ }

	~myclass()
	{
		delete str_;
	}

	std::string &get_str() const
	{
		return *str_;
	}

protected:
	std::string *str_;
};
// END
};

class ex06dc {
// [[ex06dc]]
// DEBUG descr The deep copy constructor.
class myclass 
{
public:
	// ...
	myclass(const myclass &other) :
		str_(new std::string(*other.str_))
	{ }
	// DEBUG {
public:
	myclass() :
		str_(new std::string)
	{ }

	~myclass()
	{
		delete str_;
	}

	std::string &get_str() const
	{
		return *str_;
	}

protected:
	std::string *str_;
	// DEBUG }
};
// END
};

class ex06dd {
// [[ex06dd]]
// DEBUG descr The accessor methods for read-only and read-write access.
class myclass 
{
public:
	// ...

	const std::string &get_const_str() const
	{
		return *str_;
	}

	std::string &get_str()
	{
		return *str_;
	}
	// DEBUG {
public:
	myclass() :
		str_(new std::string)
	{ }
	myclass(const myclass &other) :
		str_(new std::string(*other.str_))
	{ }

	~myclass()
	{
		delete str_;
	}

protected:
	std::string *str_;
	// DEBUG }
};
// END
};

class tmptr_token
{
};

class ex06de {
// [[ex06de]]
// DEBUG descr The empty constructor receiving a NULL reference token.
class myclass 
{
public:
	// ...
	myclass(tmptr_token &t)
	{ }
	// ...
	// DEBUG {
public:
	myclass() :
		str_(new std::string)
	{ }
	myclass(const myclass &other) :
		str_(new std::string(*other.str_))
	{ }

	~myclass()
	{
		delete str_;
	}

	const std::string &get_const_str() const
	{
		return *str_;
	}

	std::string &get_str()
	{
		return *str_;
	}

protected:
	std::string *str_;
	// DEBUG }
};
// END
};

class database;
class transaction 
{
public:
	transaction(database *db);
	// commits by default, unless rolled back
	~transaction();

	// rolls back and throws on errors
	void commit(); // explicitly commit the changes
	// return 0 on success, -1 if failed previously, or error code
	int rollback(); // roll back the transaction

	// check whether the transaction has failed
	bool has_failed() const;
};

class trans_exception : public exception
{
public:
	trans_exception(int err, const char *s) :
		trans_err_(err), msg_(s)
	{ 
	}

	~trans_exception() throw()
	{ 
	}

	virtual const char *what() const throw()
	{
		return msg_.c_str();
	}

	int trans_err_;
	std::string msg_;
};


class ex06df {
// [[ex06df]]
// DEBUG descr The destructors of varying depth.
class myclass 
{
public:
	// ...
	~myclass()
	{ }
	void destroy()
	{
		delete str_;
	}
	void destroy_tmptrs(transaction &trans)
	{ }
	// ...
	// DEBUG {
public:
	myclass() :
		str_(new std::string)
	{ }
	myclass(const myclass &other) :
		str_(new std::string(*other.str_))
	{ }
	myclass(tmptr_token &t)
	{ }

	const std::string &get_const_str() const
	{
		return *str_;
	}

	std::string &get_str()
	{
		return *str_;
	}

protected:
	std::string *str_;
	// DEBUG }
};
// END

static void full_destruction(myclass *object, transaction &trans)
{
// [[ex06dg]]
// DEBUG descr The full-depth destruction sequence.
object->destroy_tmptrs(trans);
object->destroy();
delete object;
// END
}
};

void ex06dh(database *db) {
// [[ex06dh]]
// DEBUG descr Usage of the transactions.
while(true)
{
	try {
		transaction trans(db);

		// ... do the operations ...

		trans.commit();
	} catch(trans_exception &ex) {
		continue;
	}
	break; // no exception, succeeded
}
// END
}
